#if !defined(ximera_physics_ode_shape_hpp)
#define ximera_physics_ode_shape_hpp

// -----------------------------------------------------------

#include <ximera/physics/ishape.hpp>
#include <ximera/physics/ode/ode.hpp>
#include <ximera/physics/ode/space.hpp>
#include <ximera/physics/ode/entity.hpp>

#include <vector>

namespace ximera { namespace physics { namespace ode
{
    class XIMERA_PLUGIN_API IOdeShape
    {
    public:
        virtual ~IOdeShape() {}

        virtual void detach() = 0;
        virtual void detachSpace() = 0;

        virtual void attach(Entity* entity) = 0;
        virtual void attachSpace() = 0;

        virtual Entity* entity() const = 0;
        virtual dGeomID geomID() const = 0;
    };

    template <typename T>
    class XIMERA_PLUGIN_API ShapeBase : public T, public IOdeShape
    {
    public:
        ShapeBase();
        virtual ~ShapeBase();

        virtual void detach();
        virtual void detachSpace();

        virtual void attach(Entity* entity);
        virtual void attachSpace();

        virtual Entity* entity() const { return _entity; }
        virtual dGeomID geomID() const { return _geomID; }

    protected:
        Entity* _entity;
        dGeomID _geomID;
    };

    class XIMERA_PLUGIN_API Sphere : public ShapeBase<ISphere>
    {
    public:
        Sphere();

        virtual Real radius() const;
        virtual void radius(Real value);
    };

    class XIMERA_PLUGIN_API Box : public ShapeBase<IBox>
    {
    public:
        Box();

        virtual math::Vector3 extents() const;
        virtual void extents(math::Vector3 const& value);
    };

    class XIMERA_PLUGIN_API Plane : public ShapeBase<IPlane>
    {
    public:
        Plane();

        virtual math::Plane plane() const;
        virtual void plane(math::Plane const& value);
    };

    class XIMERA_PLUGIN_API Mesh : public ShapeBase<IMesh>
    {
    public:
        Mesh();
    };
}}}

#include <ximera/physics/ode/inline/shape.inl>

// -----------------------------------------------------------

#endif
